package mspbots.data.tl.prod.autotask.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import mspbots.data.tl.base.AbstractBaseServiceImpl;
import mspbots.data.tl.entity.ResultEntity;
import mspbots.data.tl.prod.autotask.mapper.*;
import mspbots.data.tl.prod.autotask.model.*;
import mspbots.data.tl.prod.autotask.service.TaskAutotaskTicketService;
import org.springframework.beans.BeanUtils;
import org.springframework.data.relational.core.query.Criteria;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * @author Jay.Yang
 */

@Service
@Log4j2
@RequiredArgsConstructor
@DS("master")
public class TaskAutotaskTicketServiceImpl extends AbstractBaseServiceImpl<TaskAutotaskTicketMapper, TaskAutotaskTicket>
        implements TaskAutotaskTicketService {

    private final TaskAutotaskCompanyMapper companyMapper;
    private final TaskAutotaskContactMapper contactMapper;
    private final TaskAutotaskInformationMapper informationMapper;
    private final TaskAutotaskTicketRecordMapper ticketRecordMapper;

    @Override
    public void sync(ResultEntity content) {
        log.debug("Auto task tickets receiver content {}", content);
        JsonNode entity = content.getEntity();
        TaskAutotaskTicket data = TaskAutotaskTicket.builder()
                .ticketId(super.getLongValue(entity.get("id")))
                .ticketNumber(ObjectUtils.isEmpty(entity.get("ticketNumber")) ? null : entity.get("ticketNumber").asText())
                .title(ObjectUtils.isEmpty(entity.get("title")) ? null : entity.get("title").asText())
                .companyId(ObjectUtils.isEmpty(entity.get("companyID")) ? null : entity.get("companyID").asLong())
                .priority(ObjectUtils.isEmpty(entity.get("priority")) ? null : entity.get("priority").asLong())
                .ticketType(ObjectUtils.isEmpty(entity.get("ticketType")) ? null : entity.get("ticketType").asLong())
                .contactId(ObjectUtils.isEmpty(entity.get("contactID")) ? null : entity.get("contactID").asLong())
                .status(ObjectUtils.isEmpty(entity.get("status")) ? null : entity.get("status").asLong())
                .source(ObjectUtils.isEmpty(entity.get("source")) ? null : entity.get("source").asLong())
                .assignedResourceId(ObjectUtils.isEmpty(entity.get("assignedResourceID")) ? null : entity.get("assignedResourceID").asLong())
                .creatorResourceId(ObjectUtils.isEmpty(entity.get("creatorResourceID")) ? null : entity.get("creatorResourceID").asLong())
                .createDate(LocalDateTime.parse(entity.get("createDate").textValue(), DateTimeFormatter.ISO_OFFSET_DATE_TIME))
                .lastActivityDate(super.getDateTimeValue(entity.get("lastActivityDate")))
                .lastActivityResourceId(super.getLongValue(entity.get("lastActivityResourceID")))
                .currentServiceThermometerRating(super.getDoubleValue(entity.get("currentServiceThermometerRating")))
                .dueDateTime(super.getDateTimeValue(entity.get("dueDateTime")))
                .estimatedHours(super.getDoubleValue(entity.get("estimatedHours")))
                .firstResponseDateTime(super.getDateTimeValue(entity.get("firstResponseDateTime")))
                .firstResponseDueDateTime(super.getDateTimeValue(entity.get("firstResponseDueDateTime")))
                .issueType(super.getIntegerValue(entity.get("issueType")))
                .previousServiceThermometerRating(super.getDoubleValue(entity.get("previousServiceThermometerRating")))
                .queueId(super.getLongValue(entity.get("queueID")))
                .resolutionPlanDateTime(super.getDateTimeValue(entity.get("resolutionPlanDateTime")))
                .resolutionPlanDueDateTime(super.getDateTimeValue(entity.get("resolutionPlanDueDateTime")))
                .resolvedDateTime(super.getDateTimeValue(entity.get("resolvedDateTime")))
                .resolvedDueDateTime(super.getDateTimeValue(entity.get("resolvedDueDateTime")))
                .serviceThermometerTemperature(super.getDoubleValue(entity.get("serviceThermometerTemperature")))
                .subIssueType(super.getStringValue(entity.get("subIssueType")))
                .ticketCategory(super.getStringValue(entity.get("ticketCategory")))
                .completedDate(super.getDateTimeValue(entity.get("completedDate")))
                .resolution(super.getStringValue(entity.get("resolution")))
                .changeApprovalBoard(super.getIntegerValue(entity.get("changeApprovalBoard")))
                .syncTime(LocalDateTime.now())
                .build();
        data.setTenantCode(content.getTenantId());

        if (!ObjectUtils.isEmpty(data.getCompanyId())) {
            TaskAutotaskCompany company = this.companyMapper.selectOne(Wrappers.<TaskAutotaskCompany>lambdaQuery()
                    .eq(TaskAutotaskCompany::getTenantCode, data.getTenantCode())
                    .eq(TaskAutotaskCompany::getCompanyId, data.getCompanyId())
                    .last("limit 1"));
            data.setCompanyName(ObjectUtils.isEmpty(company) ? null : company.getCompanyName());
        }

        if (!ObjectUtils.isEmpty(data.getContactId())) {
            TaskAutotaskContact contact = this.contactMapper.selectOne(Wrappers.<TaskAutotaskContact>lambdaQuery()
                    .eq(TaskAutotaskContact::getTenantCode, data.getTenantCode())
                    .eq(TaskAutotaskContact::getContactId, data.getContactId())
                    .last("limit 1"));
            if (!ObjectUtils.isEmpty(contact)) {
                String firstName = StringUtils.isEmpty(contact.getFirstName()) ? "" : contact.getFirstName();
                String lastName = StringUtils.isEmpty(contact.getLastName()) ? "" : contact.getLastName();
                data.setContactName(firstName + " " + lastName);
            }
        }

        List<TaskAutotaskInformation> informationList = this.informationMapper.selectList(Wrappers.<TaskAutotaskInformation>lambdaQuery()
                .eq(TaskAutotaskInformation::getTenantCode, data.getTenantCode())
                .eq(TaskAutotaskInformation::getType,"Tickets")
                .in(TaskAutotaskInformation::getName, List.of("Status", "Priority", "Source", "TicketType","QueueID","ChangeApprovalBoard")));
        setNameInfo(data, informationList);

        splicLink(content,data);

        TaskAutotaskTicket dbData = super.baseMapper.selectOne(Wrappers.<TaskAutotaskTicket>lambdaQuery()
                .eq(TaskAutotaskTicket::getTenantCode, data.getTenantCode())
                .eq(TaskAutotaskTicket::getTicketId, data.getTicketId())
                .last("limit 1"));
        if (ObjectUtils.isEmpty(dbData)) {
            super.baseMapper.insert(data);
        } else {
            data.setId(dbData.getId());
            super.baseMapper.updateById(data);
        }

        //process ticket record
        TaskAutotaskTicketRecord record = TaskAutotaskTicketRecord.builder().build();
        BeanUtils.copyProperties(data,record);
        record.setId(null);
        record.setLastActivityResourceId(ObjectUtils.isEmpty(entity.get("lastActivityResourceID"))
                ? null : entity.get("lastActivityResourceID").asLong());
        TaskAutotaskTicketRecord recordDb = this.ticketRecordMapper.selectOne(Wrappers.<TaskAutotaskTicketRecord>lambdaQuery()
                .eq(TaskAutotaskTicketRecord::getTenantCode, data.getTenantCode())
                .eq(TaskAutotaskTicketRecord::getTicketId, data.getTicketId())
                .orderByDesc(TaskAutotaskTicketRecord::getStatusDate)
                .last("limit 1"));

        if (ObjectUtils.isEmpty(recordDb) || !recordDb.getStatus().equals(data.getStatus())){
            record.setStatusDate(record.getSyncTime());
            this.ticketRecordMapper.insert(record);
        }else{
            record.setId(recordDb.getId());
            this.ticketRecordMapper.updateById(record);
        }
    }



    private void splicLink(ResultEntity content, TaskAutotaskTicket data){
        String url = this.databaseClient.select().from(SysDictDataEntity.class)
                .matching(Criteria.where("tenantCode").is(content.getTenantId())
                        .and("subjectCode").is("AUTOTASK")
                        .and("dictLabel").is("baseUrl"))
                .fetch().one().map(SysDictDataEntity::getDictValue).block(Duration.ofSeconds(10));
        log.info("tenantCode:{},ticketId:{}  url:{}",content.getTenantId(),data.getTicketId(),url);
        if(!ObjectUtils.isEmpty(url)){
            url=url.trim();
            StringBuilder str2= new StringBuilder();

            for (int i = 0; i < url.length(); i++) {
                if (url.charAt(i) >= 48 && url.charAt(i) <= 57) {
                    str2.append(url.charAt(i));
                }
            }

            log.info("tenantCode:{}  ticketId:{} str2:{}",content.getTenantId(),data.getTicketId(),str2.toString());
            String ticketUrl = "https://ww"+str2.toString()+".autotask.net/Mvc/ServiceDesk/TicketDetail.mvc?workspace=False&ticketId="+data.getTicketId();
            data.setLink(ticketUrl);
        }
    }




    @Override
    public void setNameInfo(TaskAutotaskTicket data, List<TaskAutotaskInformation> informationList) {
        if (!CollectionUtils.isEmpty(informationList)) {
            informationList.forEach(information -> {
                if (!ObjectUtils.isEmpty(data.getStatus())
                        && "Status".equalsIgnoreCase(information.getName())
                        && data.getStatus().toString().equals(information.getValue())) {
                    data.setStatusName(information.getLabel());
                } else if (!ObjectUtils.isEmpty(data.getPriority())
                        && "Priority".equalsIgnoreCase(information.getName())
                        && data.getPriority().toString().equals(information.getValue())) {
                    data.setPriorityName(information.getLabel());
                } else if (!ObjectUtils.isEmpty(data.getSource())
                        && "Source".equalsIgnoreCase(information.getName())
                        && data.getSource().toString().equals(information.getValue())) {
                    data.setSourceName(information.getLabel());
                } else if (!ObjectUtils.isEmpty(data.getTicketType())
                        && "TicketType".equalsIgnoreCase(information.getName())
                        && data.getTicketType().toString().equals(information.getValue())) {
                    data.setTicketTypeName(information.getLabel());
                }else if (!ObjectUtils.isEmpty(data.getQueueId())
                        && "QueueID".equalsIgnoreCase(information.getName())
                        && data.getQueueId().toString().equals(information.getValue())) {
                    data.setQueueIdName(information.getLabel());
                }else if (!ObjectUtils.isEmpty(data.getChangeApprovalBoard())
                        && "ChangeApprovalBoard".equalsIgnoreCase(information.getName())
                        && data.getChangeApprovalBoard().toString().equals(information.getValue())) {
                    data.setChangeApprovalBoardName(information.getLabel());
                }
            });
        }
    }
}
